package com.dk.util;

import gnu.io.*;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.TooManyListenersException;

import static java.lang.System.out;

public class RFIDUtil {
    static SerialPort serialPort = null;
    static StringBuffer sb = new StringBuffer();
    static BufferedInputStream bis = null;
    List<Byte> tagListBeforeDeal = new ArrayList<Byte>();
    //添加标签数据到List
    public List<Byte> addBytesToList(byte[] byteArr) {

        synchronized (tagListBeforeDeal) {

            for(int i=0; i < byteArr.length; i++) {

                tagListBeforeDeal.add(byteArr[i]);

            }
        }
        return tagListBeforeDeal;
    }

    public static List<Byte> addByteArrToList (byte[] byteArr){
        List<Byte> list = new ArrayList<Byte>();
        for (int i = 0;i<byteArr.length;i++){
            list.add(byteArr[i]);
        }
        return list;
    }
    public static byte[] readCommand() {

        byte[] byteArr = {(byte)0xA0,0x04,0x01,(byte) 0x74,0x07, (byte)0xE0};
        byte crc = CheckSum(byteArr, 0, byteArr.length-2);
        byteArr[byteArr.length-1] = crc;
        //curAnt = (curAnt+1) % 8;A0 04 01 89 01 D1
        return byteArr;
    }
    public static byte[] setNextAnt() {

        byte[] byteArr = {(byte)0xA0,0x04,0x01,(byte) 0x89,(byte)0x01, (byte)0xD1};
        byte crc = CheckSum(byteArr, 0, byteArr.length-2);
        byteArr[byteArr.length-1] = crc;
        //curAnt = (curAnt+1) % 8;A0 04 01 89 01 D1
        return byteArr;
    }
    public  static byte CheckSum(byte[]byteArr, int from, int to) {

        int INIT_VALUE = 0;
        int curValue = 0;
        for(int i = from; i <= to; i++){

            curValue = byteToInt(byteArr[i]);
            INIT_VALUE = INIT_VALUE + curValue;
        }
        INIT_VALUE = (~INIT_VALUE)+1;
        byte[] mBytes = intToBytes(INIT_VALUE);
        return mBytes[3];
    }
    public static byte CheckSum(List<Byte> mlist, int from, int to) {

        int INIT_VALUE = 0;
        int curValue = 0;
        for(int i = from; i <= to; i++){

            curValue = byteToInt(mlist.get(i));
            INIT_VALUE = INIT_VALUE + curValue;
        }
        INIT_VALUE = (~INIT_VALUE)+1;
        byte[] mBytes = intToBytes(INIT_VALUE);
        return mBytes[3];
    }

    public static byte[] intToBytes(int i) {
        byte[] b = new byte[4];
        b[0] = (byte) (i >>> 24);
        b[1] = (byte) (i >>> 16);
        b[2] = (byte) (i >>> 8);
        b[3] = (byte) i;
        return b;
    }
    public static int byteToInt(byte data) {

        byte[] b = {0x00,0x00,0x00,data};
        return bytesToInt(b);
    }
    public static int bytesToInt(byte[] b) {
        int i = (b[0] << 24) & 0xFF000000;
        i |= (b[1] << 16) & 0xFF0000;
        i |= (b[2] << 8) & 0xFF00;
        i |= b[3] & 0xFF;
        return i;
    }
    /**
     * 添加监听器
     * @param port     串口对象
     * @param listener 串口监听器
     * @throws TooManyListeners 监听类对象过多
     */
    public static void addListener( SerialPort port, SerialPortEventListener listener) {

        try {

            //给串口添加监听器
            port.addEventListener(listener);
            //设置当有数据到达时唤醒监听接收线程
            port.notifyOnDataAvailable(true);
            //设置当通信中断时唤醒中断线程
            port.notifyOnBreakInterrupt(true);

        } catch (TooManyListenersException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从串口读取数据
     * @param serialPort 当前已建立连接的SerialPort对象
     * @return 读取到的数据
     * @throws ReadDataFromSerialPortFailure 从串口读取数据时出错
     * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错
     */
    public static byte[] readFromPort(SerialPort serialPort) throws IOException {

        InputStream in = null;
        byte[] bytes = null;

        try {
            in = serialPort.getInputStream();
            int bufflenth = in.available();        //获取buffer里的数据长度
            bis = new BufferedInputStream(in,400);
            while (bufflenth >20) {
                bytes = new byte[bufflenth];    //初始化byte数组为buffer中数据的长度
                bis.read(bytes);
                bufflenth = in.available();
            }
        }  finally {
            //  if (in != null) {
            in.close();
            in = null;
            // }
        }
        return bytes;
    }

    /**
     * 往串口发送数据
     * @param serialPort 串口对象
     * @param order    待发送数据
     * @throws SendDataToSerialPortFailure 向串口发送数据失败
     * @throws SerialPortOutputStreamCloseFailure 关闭串口对象的输出流出错
     */
    public static void sendToPort(SerialPort serialPort, byte[] order) {

        OutputStream out = null;

        try {

            out = serialPort.getOutputStream();
            out.write(order);
            out.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                    out = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    /**
     * 打开串口
     * @param portName 端口名称
     * @param baudrate 波特率
     * @return 串口对象
     * @throws Exception
     * @throws SerialPortParameterFailure 设置串口参数失败
     * @throws NotASerialPort 端口指向设备不是串口类型
     * @throws NoSuchPort 没有该端口对应的串口设备
     * @throws PortInUse 端口已被占用
     */
    public static final SerialPort openPort(String portName, int baudrate) throws PortInUseException, NoSuchPortException {


        //通过端口名识别端口
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

        //打开端口，并给端口名字和一个timeout（打开操作的超时时间）
        CommPort commPort = portIdentifier.open(portName, 2000);

        //判断是不是串口
        if (commPort instanceof SerialPort) {

            SerialPort serialPort = (SerialPort) commPort;

            try {
                //设置一下串口的波特率等参数
                serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            } catch (UnsupportedCommOperationException e) {
                e.printStackTrace();
            }

            //System.out.println("Open " + portName + " sucessfully !");
            return serialPort;

        }
        else {
            //不是串口
            out.println("不是串口");
            return null;
        }
    }

    public static String byteToString(byte[] req){
        StringBuffer str = new StringBuffer();
        List<String> strs = new ArrayList<String>();
        for(int i = 0;i<req.length;i++){
            int v = req[i] & 0xFF;
            String hv = Integer.toHexString(v).toUpperCase();
            if(hv.length() < 2){
                strs.add("0"+hv);
            }
            else{
                strs.add(hv);
            }
        }
        for (String string : strs) {
            str.append(string);
        }

        return str.toString();
    }

    public static String praseTag(List<Byte> mbList,DataMark mDataMark) {

       /* if(mbList.get(mDataMark.start+4)== 0x00) {

            return null;
        }*/
        return bytes2Hex_noSpace(mbList, mDataMark.start+7, mDataMark.end-2);
    }
    public static String bytes2Hex_noSpace(List<Byte> mList,int from, int to) {

        String hex = "";
        for(int i = from; i <= to; i++) {

            hex = hex +byte2Hex(mList.get(i));
        }
        return hex;
    }
    public static String byte2Hex(byte b) {

        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;
        }
        return hex;
    }



}
